package com.sj.purchase.modules.cost.service.order;

import com.sj.purchase.modules.cost.domain.order.OutOrderItem;
import com.sj.purchase.modules.cost.domain.imei.Inventory;
import com.sj.purchase.modules.cost.domain.order.Order;
import com.sj.purchase.modules.cost.domain.order.OutOrder;
import com.sj.purchase.modules.cost.domain.price.CostPrice;
import com.sj.purchase.modules.cost.repository.imei.InventoryRepository;
import com.sj.purchase.modules.cost.repository.order.OutOrderRepository;
import com.sj.purchase.modules.cost.service.price.CostPriceService;
import com.sj.purchase.modules.cost.views.out_order.InventoryItemCostVO;
import com.sj.purchase.modules.cost.views.out_order.OutOrderCostVO;
import com.sj.purchase.util.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by Alin on 2017/11/25.
 */
@Service
public class OutOrderItemCostService {

    @Autowired
    private OutOrderRepository outOrderRepository;

    @Autowired
    private InventoryRepository inventoryRepository;

    @Autowired
    private CostPriceService costPriceService;

    public Page<OutOrderCostVO> search(String orderNo, Date startdDate, Date endDate, Pageable pageable) {
        try {
            List<Inventory> inventoryList = new ArrayList<>();
            List<OutOrder> outOrderList = new ArrayList<>();

            if (orderNo != null && orderNo != "") {
                OutOrder outOrder1 = outOrderRepository.findFirstByOrderNo(orderNo);
                outOrderList.add(outOrder1);
                inventoryList = inventoryRepository.findByOutOrderNo(outOrder1.getOrderNo());
                List<OutOrderCostVO> outOrderCostVOS = getList(inventoryList, outOrderList);
                return new PageImpl<>(outOrderCostVOS, pageable, outOrderCostVOS.size());
            } else {
                if (pageable != null) {
                    //查询和导出 都是缓存比较快
                    Map<String, List<CostPrice>> skuCostPriceMap = costPriceService.getSkuCostPriceCache(costPriceService.listCostPrice(DateUtils.addDays(startdDate, -7), endDate));
                    Page<OutOrder> outOrderPageList = null;
                    outOrderPageList = outOrderRepository.findByCreateDateBetweenAndOrderNoIsNotNullAndTypeNot(startdDate, endDate, Order.OrderType.OUT_PROCUREMENT_RETURNS, pageable);
                    if (outOrderPageList != null) {
                        outOrderList = outOrderPageList.getContent();
                    }
                    if (outOrderList != null && outOrderList.size() >= 0) {
                        //分页的话 把查出来的订单号 转换成集合 通过in来查询串码数据
                        String[] orderNoList = outOrderList.stream().map(OutOrder::getOrderNo).toArray(String[]::new);
                        inventoryList = inventoryRepository.findByOutOrderNoIn(orderNoList);
                    }
                    return new PageImpl<>(getList(inventoryList, outOrderList, skuCostPriceMap), pageable, outOrderPageList.getTotalElements());
                } else {
                    //获取移动平均成本价
                    inventoryList = inventoryRepository.findByOutStockDateBetweenAndOutOrderNoIsNotNull(startdDate, endDate);
                    Map<String, List<CostPrice>> skuCostPriceMap = costPriceService.getSkuCostPriceCache(costPriceService.listCostPrice(DateUtils.addDays(startdDate, -10), endDate));
                    outOrderList = outOrderRepository.findByCreateDateBetweenAndOrderNoIsNotNullAndTypeNot(startdDate, endDate, Order.OrderType.OUT_PROCUREMENT_RETURNS);
                    //不分页 根据出库时间来获取串码数据 不用一条一条根据订单号查询 提高效率
                    return new PageImpl<>(getList(inventoryList, outOrderList, skuCostPriceMap), pageable, outOrderList.size());

                }

            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public List<OutOrderCostVO> getList(List<Inventory> inventoryList, List<OutOrder> outOrderList, Map<String, List<CostPrice>> skuCostPriceMap) {
        System.out.println("组装开始："+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        DecimalFormat df = new DecimalFormat("#.##");
        List<OutOrderCostVO> outOrderInventoryItemVOList = new ArrayList<>();
        //根据订单号和 sku分组
        Map<String, Map<String, List<Inventory>>> inventoryMap = inventoryList.stream().collect(Collectors.groupingBy(Inventory::getOutOrderNo)).entrySet()
                .stream().collect(Collectors.toMap(
                        stringListEntry -> stringListEntry.getKey(),
                        stringListEntry -> stringListEntry.getValue().stream().collect(Collectors.groupingBy(Inventory::getSkuNo))
                ));
        for (OutOrder outOrder : outOrderList) {
            OutOrderCostVO outOrderInventoryItemVO = new OutOrderCostVO();
            outOrderInventoryItemVO.setOrderNo(outOrder.getOrderNo());//订单号
            outOrderInventoryItemVO.setShopName(outOrder.getShopName());//卖家
            outOrderInventoryItemVO.setBuyerName(outOrder.getBuyerName());//买家
            outOrderInventoryItemVO.setCreateDate(outOrder.getCreateDate());//出库时间
            Double payMent = 0.0;
            payMent = outOrder.getPayment();
//            System.out.println(payMent);
//            if(payMent!=null){
//                payMent = convert(payMent)
//            }
            outOrderInventoryItemVO.setPayment(payMent);//订单实付金额

            //orderItems
            Set<OutOrderItem> orderItems = outOrder.getOrderItems();
            List<OutOrderItem> orderItemList = orderItems.stream().collect(Collectors.toList());
            List<InventoryItemCostVO> inventoryItemVOList = new ArrayList<>();
            Double orderAvgPrice = 0.0;
            Double orderImeiPrice = 0.0;

            for (OutOrderItem item : orderItemList) {
                InventoryItemCostVO inventoryItemVO = new InventoryItemCostVO();
                inventoryItemVO.setSkuNo(item.getSkuNo());
                inventoryItemVO.setNum(item.getNum());
                Double price = item.getPrice();
                inventoryItemVO.setPrice(price);
                Double avgPrice = 0D;
                Double avgPriceSum = 0D;
                if (skuCostPriceMap != null) {
                    avgPrice = costPriceService.getCostPrice(skuCostPriceMap, item.getSkuNo(), outOrder.getCreateDate());
                } else {
                    avgPrice = costPriceService.getCostPrice(item.getSkuNo(), outOrder.getCreateDate());
                }
                if (avgPrice != null) {
                    avgPriceSum = avgPrice * item.getNum();
                    orderAvgPrice += avgPriceSum;
                }
                inventoryItemVO.setAvgPrice(convert(avgPrice));
                Map<String, List<Inventory>> inventoryMapListByOrderNo = inventoryMap.get(item.getOrder().getOrderNo());
                if (inventoryMapListByOrderNo != null && inventoryMapListByOrderNo.size() > 0) {//明细中存在该订单号
                    List<Inventory> inventoryMapListBySkuNo = inventoryMapListByOrderNo.get(item.getSkuNo());//根据sku查询有无该串码数据 无串码则是配件之类 数据置空 计算价格
                    if (inventoryMapListBySkuNo != null && inventoryMapListBySkuNo.size() > 0) {
                        for (Inventory inventory : inventoryMapListBySkuNo) {
                            inventoryItemVO.setSkuName(inventory.getSkuName());
                            // 一个item对应多个IMEI，这里只取了最后一个，出库串码数，不当从这里获取，重新sql查询。
                            inventoryItemVO.setImei(inventory.getId().getImei());
                            inventoryItemVO.setInOrderNo(inventory.getInOrderNo());
                            inventoryItemVO.setReferNo(inventory.getReferNo());
                            Double costPrice = inventory.getCostPrice();
                            inventoryItemVO.setCostPrice(convert(costPrice));
                            inventoryItemVO.setProfit1(price != null && costPrice != null ? convert(price - costPrice) : 0.0);//sku 利润1 = sku单价 - 唯一码成本价
                            inventoryItemVO.setProfit2(price != null && avgPriceSum != null ? convert(price - avgPriceSum) : 0.0);//  sku 利润2 = sku单价 - 移动平均成本价
                            if (costPrice != null) {
                                orderImeiPrice += costPrice;
                            }
                            inventoryItemVOList.add(inventoryItemVO);
                        }
                    } else {
                        inventoryItemVO.setCostPrice(convert(avgPrice));//无唯一码的 唯一成本价按平均成本价
                        inventoryItemVO.setProfit1(price != null && avgPriceSum != null ? convert(price - avgPriceSum) : 0.0);//无唯一码的 唯一码成本价按照移动平均成本价计算
                        inventoryItemVO.setProfit2(price != null && avgPriceSum != null ? convert(price - avgPriceSum) : 0.0);
                        if (avgPriceSum != null) {
                            orderImeiPrice += avgPriceSum;
                        }
                        inventoryItemVOList.add(inventoryItemVO);
                    }
                } else {
                    inventoryItemVO.setCostPrice(convert(avgPrice));//无唯一码的 唯一成本价按平均成本价
                    inventoryItemVO.setProfit1(price != null && avgPriceSum != null ? convert(price - avgPriceSum) : 0.0);//无唯一码的 唯一码成本价按照移动平均成本价计算
                    inventoryItemVO.setProfit2(price != null && avgPriceSum != null ? convert(price - avgPriceSum) : 0.0);
                    if (avgPriceSum != null) {
                        orderImeiPrice += avgPriceSum;
                    }
                    inventoryItemVOList.add(inventoryItemVO);
                }
            }
            outOrderInventoryItemVO.setCostPrice1(orderImeiPrice != null ? convert(orderImeiPrice) : orderImeiPrice);//订单成本价1 = 订单明细sku唯一吗成本价的和
            outOrderInventoryItemVO.setCostPrice2(orderAvgPrice != null ? convert(orderAvgPrice) : orderAvgPrice);//订单成本价2 = 订单明细sku移动平均成本价的总和
            outOrderInventoryItemVO.setProfit1(orderImeiPrice != null && payMent != null ? convert(payMent - orderImeiPrice) : 0.0);//订单利润1 = 订单实付金额 - 订单成本价1
            outOrderInventoryItemVO.setProfit2(orderAvgPrice != null && payMent != null ? convert(payMent - orderAvgPrice) : 0.0);//订单利润2 = 订单实付金额 - 订单成本价2
            outOrderInventoryItemVO.setInventoryItems(inventoryItemVOList.stream().collect(Collectors.toSet()));
            outOrderInventoryItemVOList.add(outOrderInventoryItemVO);
        }
        return outOrderInventoryItemVOList;
    }

    public List<OutOrderCostVO> getList(List<Inventory> inventoryList, List<OutOrder> outOrderList) {
        List<Date> outOrderCreateDateList = outOrderList.stream().map(OutOrder::getCreateDate).sorted().collect(Collectors.toList());
        Date start = outOrderCreateDateList.get(0);
        Date end = outOrderCreateDateList.get(outOrderCreateDateList.size()-1);
        Map<String, List<CostPrice>> skuCostPriceCache = costPriceService.getSkuCostPriceCache(costPriceService.listCostPrice(start,end));
        return getList(inventoryList, outOrderList, skuCostPriceCache);
    }

    static double convert(double value) {
        long l1 = Math.round(value * 100); //四舍五入
        double ret = l1 / 100.0; //注意:使用 100.0 而不是 100
        return ret;
    }
}
